package editor.widgets;

import observer.IntObserver;
import observer.ObservedInt;

import javax.swing.*;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import java.awt.*;

/**
 * This is a {@link javax.swing.JComboBox} that automatically updates the {@link ObservedInt} that it manages,
 * so that the model is updated properly.
 *
 * FIXME: This doesn't support being updated from outside the widget (e.g. undos) like {@link ObservedStringField} does.
 *
 * @author Neil Dickson
 */
public class ObservedIntComboBox extends JComboBox implements IntObserver, AncestorListener {
	private ObservedInt value;

	public ObservedIntComboBox(ObservedInt value,int[] possibleValues) {
		super();
		for (int i : possibleValues) {
			addItem(i);
		}
		this.value = value;
		setSelectedItem(value.get(),false);
		value.addObserver(this);
		addAncestorListener(this);
	}

	public void valueChanged(ObservedInt i) {
		setSelectedItem(i.get(),false);
	}

	public void setSelectedItem(Integer i,boolean updateValue) {
		super.setSelectedItem(i);
		if (updateValue) {
			value.set(this,i);
		}
	}

	public void setSelectedItem(Object i) {
		if (i instanceof Integer) {
			setSelectedItem((Integer)i,true);
		}
		else {
			throw new ClassCastException("ObservedIntComboBox doesn't contain items of class "+i.getClass().getName());
		}
	}

	public void setSelectedIndex(int index) {
		super.setSelectedIndex(index);
		value.set(this,((Integer)getItemAt(index)));
	}

	public void setBackground(Color bg) {
		super.setBackground(bg);
		setOpaque(bg.getAlpha()==255);
	}

	public void ancestorAdded(AncestorEvent event) {
		value.addObserver(this);
	}

	public void ancestorRemoved(AncestorEvent event) {
		value.removeObserver(this);
	}

	public void ancestorMoved(AncestorEvent event) {}

	/**
	 * Paints this combo box, but first checks for a bug in Java's implementation of JComboBox on Windows
	 * @param g
	 */
	protected void paintComponent(Graphics g) {
		if (getWidth()>=0x4000 || getHeight()>=0x4000) {
			System.err.println("JComboBox bug occurred with size: "+getSize());
			FontMetrics font = getFontMetrics(getFont());
			Dimension dim = new Dimension(24,24);
			for (int i=0; i<getItemCount(); ++i) {
				dim.width = Math.max(dim.width,20+font.stringWidth(getItemAt(i).toString()));
			}
			System.err.println("Setting it to size: "+dim);
			setMinimumSize(dim);
			setPreferredSize(dim);
			setMaximumSize(dim);
			setSize(dim);
		}
		super.paintComponent(g);
	}
}
